-- vim: set autoindent noexpandtab tabstop=4 shiftwidth=4 softtabstop=-1:
--
local mtm = {}

-- table: store setting from world.mt file
mtm.worldmt = {}

mtm.name = 'mod_mtm'

mtm.reservedNames = {
	worldbase_log = true
}

-- string: Backend storage used
function mtm.getWorldmt()
	if #mtm.worldmt > 0 then
		return mtm.worldmt
	end

	local fileName = minetest.get_worldpath() .. '/world.mt'
	local file = assert(
		io.open(fileName, 'r'),
		'Error loading file : ' .. fileName
	)

	local data = {}

	for line in file:lines() do
		local key, value = line:match('^([%w|_]+)%s-=%s-(.+)$')

		key   = string.gsub(key, '^%s*(.-)%s*$', '%1')
			value = string.gsub(value, '^%s*(.-)%s*$', '%1')

		if key and value ~= nil then
			if tonumber(value) then
			  value = tonumber(value)
			elseif value == 'true' then
			  value = true
			elseif value == 'false' then
			  value = false
			end

			if tonumber(key) then
				key = tonumber(key)
			end

			data[key] = value
		end
	end

	assert(next(data) ~= nil, fileName .. ' appears to be empty.')

	mtm.worldmt = data

	return data
end

function mtm.getBackend()
	if mtm.worldmt['world_backend'] then
		return mtm.worldmt['world_backend']
	end

	if mtm.worldmt['backend'] == 'postgresql' then
		return mtm.worldmt['backend']
	end

	return 'sqlite3'
end

function mtm.getConnect(backend)
	if backend == 'sqlite3' then
		return minetest.get_worldpath() .. '/world.sqlite'
	elseif mtm.worldmt['backend'] == 'postgresql' then
		minetest.log('error', 'pgsql_connection not set in world.mt.')
		assert(
			mtm.worldmt['pgsql_connection'] ~= nil,
			'pgsql_connection not set in world.mt.'
		)
			return mtm.worldmt['pgsql_connection']
	end
end

function mtm.storage(name, backend, connect)
	if not name then
		name = 'mod_' .. minetest.get_current_modname()
	elseif string.sub(name, 1, 4) == 'mod_' then
		assert(
			name == 'mod_' .. minetest.get_current_modname(),
			'Illegal storage name. Reserved for a specific mod.'
		)
	end

	assert(mtm.reservedNames[name] == nil, 'Reserved storage name used.')

	if not backend then
		backend = mtm.getBackend()
	end

	if not connect then
		connect = mtm.getConnect(backend)
	end

	local opts = {}
	opts.db = backend
	opts.name = name

	if backend == 'sqlite3' then
		opts.file = connect
	else
		opts.connection = connect
	end

	minetest.log('info', 'mod_mtm db \'' .. name .. '\' accessed.')

	return mtm.dbtable.new(opts)
end

function mtm.setPackagepath()
	package.path = package.path .. ';' .. minetest.get_modpath('mtm') .. '/packages/?.lua'
end

function mtm.init()
	mtm.getWorldmt()
	mtm.setPackagepath()

	assert(mtm.worldmt['backend'] ~= nil, 'backend missing from world.mt')

	mtm.dbtable = assert(
		require('dbtable'),
		'Unable to require dbtable. mtm must be listed as a trusted mod?'
	)
end

mtm.init()

_G.mtm = mtm

minetest.log('info', 'Minetest.Me(mtm) mod loaded.')
